home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / comm / msged400.zip / src / dlgbox.c < prev    next >
C/C++ Source or Header  |  1996-07-24  |  16KB  |  614 lines

  1. /*
  2.  *  DLGBOX.C
  3.  *
  4.  *  Written on 10-Jul-94 by John Dennis and released to the public domain.
  5.  *
  6.  *  DialogBox Code.  Also includes the system HotSpot code.
  7.  *
  8.  *
  9.  *  A dialog box consists of the main dlgbox structure, which defines
  10.  *  colours and window position and the like, plus the dialog controls
  11.  *  themselves (buttons, fields etc).  Each control has a corresponding
  12.  *  HotSpot and ID, which allows any mouse press/release/movement to be
  13.  *  related to a hotspot and corresponding control ID.  Other hotspots
  14.  *  may be in the system, but note that if a hotspot is associated with
  15.  *  a window, it will only be looked at if that window is current (on top).
  16.  *
  17.  *  This windowing system is NOT event based in the same manner as
  18.  *  Windows.  It's done this way to make non-event based programs easily
  19.  *  portable to this system; and as a result flexibility suffers.  If you
  20.  *  want to add new types, you will have to recompile the affected
  21.  *  modules.
  22.  *
  23.  *  Caveats: If a new ctrl type is wanted, it MUST be added here if it
  24.  *    is to be processed by/for the DoDialog function.  You must also
  25.  *    add the display function somwhere & link it in.
  26.  *           Functions to lookout for (that need mods):
  27.  *                  DoDialog();
  28.  *                  ShowCtrl();
  29.  *                  DoCursor();
  30.  *                  GetYCoord();
  31.  *                  BuildDialogHot();
  32.  *
  33.  */
  34.  
  35. #define DLGBOX
  36.  
  37. #include "unused.h"
  38.  
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include "winsys.h"
  43. #include "menu.h"
  44. #include "keys.h"
  45.  
  46. void BuildDialogHot(dlgbox * db, HotGroup * hot);
  47.  
  48. /*
  49.    **
  50.    **      Global vars used by all functions.
  51.    **
  52.  */
  53.  
  54. static int Focus = -1;
  55. static int OldFocus = -1;
  56.  
  57. /*
  58.    **
  59.    **      The Functions themselves.
  60.    **
  61.  */
  62.  
  63. /* void *SetFocus(int id, int wid);
  64.    **
  65.    ** Returns the ctrl associated with the
  66.    ** id and wid.  Not used currently...
  67.    *
  68.  
  69.    void *SetFocus(int id, int wid)
  70.    {
  71.    int gr, it;
  72.  
  73.    for (gr = 0; gr < NumHots; gr++)
  74.    {
  75.    if (!wid || HotSpot[gr]->wid == wid)
  76.    {
  77.    for (it = 0; it < HotSpot[gr]->num; it++)
  78.    {
  79.    if (HotSpot[gr]->harr[it].id == id)
  80.    {
  81.    return (void *) HotSpot[gr]->harr[it].ctl;
  82.    }
  83.    }
  84.    }
  85.    }
  86.    return NULL;
  87.    }
  88.  */
  89.  
  90. /* int DoEditField(int *p1, int *p2, editf *i, int wid)
  91.    **
  92.    ** A dummy MnuGetMsg used when an edit feild has focus,
  93.    ** it handles all the msgs it understands and passes others
  94.    ** back to the DoDialog() procedure.
  95.  */
  96.  
  97. int DoEditField(EVT * event, editf * i, unsigned long wid)
  98. {
  99.     int ret;
  100.     int pos = i->curpos;
  101.  
  102.     unused(wid);
  103.     ret = WGetLine(i->x, i->y, i->len, i->buf, i->sattr, &pos, 1, 0, 0, event);
  104.  
  105.     i->curpos = pos;
  106.  
  107.     return ret;
  108. }
  109.  
  110. /* static void ShowCtrl(ctrl *i, unsigned char sel);
  111.    **
  112.    ** Shows a dialog box controls.  Also used to show
  113.    ** whether a control has been selected or not.
  114.  */
  115.  
  116. static void ShowCtrl(ctrl * i, unsigned char sel)
  117. {
  118.     switch (i->type)
  119.     {
  120.     case D_EDT:
  121.         ((editf *) i->ctl)->select = sel;
  122.         ShowEditField((editf *) i->ctl);
  123.         break;
  124.  
  125.     case D_BUT:
  126.         ((button *) i->ctl)->select = sel;
  127.         ShowButton((button *) i->ctl);
  128.         break;
  129.  
  130.     case D_CHK:
  131.         ((ckbutton *) i->ctl)->select = sel;
  132.         ShowCkbutton((ckbutton *) i->ctl);
  133.         break;
  134.  
  135.     case D_TXT:
  136.         D_ShowTxt((textl *) i->ctl);
  137.         break;
  138.  
  139.     case D_WBX:
  140.         D_ShowWBox((wbox *) i->ctl);
  141.         break;
  142.  
  143.     default:
  144.         break;
  145.     }
  146. }
  147.  
  148. /* void DoCursor(dlgbox *db, int foc);
  149.    **
  150.    ** Handles the placement of the cursor, if needed.
  151.    **
  152.  */
  153.  
  154. void DoCursor(dlgbox * db, int foc)
  155. {
  156.     if (!db)
  157.     {
  158.         TTCurSet(0);
  159.         return;
  160.     }
  161.     switch (db->ctrls[foc].type)
  162.     {
  163.     case D_CHK:
  164.         Wgotoxy(((ckbutton *) db->ctrls[foc].ctl)->x + 2, ((ckbutton *) db->ctrls[foc].ctl)->y);
  165.         TTCurSet(1);
  166.         break;
  167.  
  168.     default:
  169.         TTCurSet(0);
  170.         break;
  171.     }
  172. }
  173.  
  174. int ValidCtrl(int type)
  175. {
  176.     switch (type)
  177.     {
  178.     case D_WBX:
  179.     case D_TXT:
  180.         return 0;
  181.     default:
  182.         return 1;
  183.     }
  184. }
  185.  
  186. int GetPrevCtrl(dlgbox * db, int cur)
  187. {
  188.     int foc = cur;
  189.  
  190.     if ((--foc) < 0)
  191.         foc = db->num - 1;
  192.  
  193.     while (foc != cur && !ValidCtrl(db->ctrls[foc].type))
  194.     {
  195.         if ((--foc) < 0)
  196.             foc = db->num - 1;
  197.     }
  198.  
  199.     return foc;
  200. }
  201.  
  202. int GetNextCtrl(dlgbox * db, int cur)
  203. {
  204.     int foc = cur;
  205.  
  206.     if ((++foc) == db->num)
  207.         foc = 0;
  208.  
  209.     while (foc != cur && !ValidCtrl(db->ctrls[foc].type))
  210.     {
  211.         if ((++foc) == db->num)
  212.             foc = 0;
  213.     }
  214.  
  215.     return foc;
  216. }
  217.  
  218. int GetYCoord(ctrl * i)
  219. {
  220.     switch (i->type)
  221.     {
  222.     case D_BUT:
  223.         return ((button *) i->ctl)->y;
  224.     case D_CHK:
  225.         return ((ckbutton *) i->ctl)->y;
  226.     case D_EDT:
  227.         return ((editf *) i->ctl)->y;
  228.     default:
  229.         return 0;
  230.     }
  231. }
  232.  
  233. int GetRightCtrl(dlgbox * db, int cur, int num)
  234. {
  235.     int y = GetYCoord(&db->ctrls[cur]);
  236.     int i;
  237.  
  238.     for (i = cur + 1; i < num; i++)
  239.     {
  240.         if (GetYCoord(&db->ctrls[i]) == y && ValidCtrl(db->ctrls[i].type))
  241.             return i;
  242.     }
  243.     for (i = 0; i < cur; i++)
  244.     {
  245.         if (GetYCoord(&db->ctrls[i]) == y && ValidCtrl(db->ctrls[i].type))
  246.             return i;
  247.     }
  248.     return cur;
  249. }
  250.  
  251. int GetLeftCtrl(dlgbox * db, int cur, int num)
  252. {
  253.     int y = GetYCoord(&db->ctrls[cur]);
  254.     int i;
  255.  
  256.     for (i = cur - 1; i >= 0; i--)
  257.     {
  258.         if (GetYCoord(&db->ctrls[i]) == y && ValidCtrl(db->ctrls[i].type))
  259.             return i;
  260.     }
  261.     for (i = num; i > cur; i--)
  262.     {
  263.         if (GetYCoord(&db->ctrls[i]) == y && ValidCtrl(db->ctrls[i].type))
  264.             return i;
  265.     }
  266.     return cur;
  267. }
  268.  
  269. int GetFocus(dlgbox * db, int id)
  270. {
  271.     int i;
  272.  
  273.     for (i = 0; i < db->num; i++)
  274.         if (db->ctrls[i].id == id)
  275.             return i;
  276.  
  277.     return -1;
  278. }
  279.  
  280. /* int DoDialog(dlgbox *db, int wnd);
  281.    **
  282.    ** Process a dialogbox structure (dlgbox), incorporating
  283.    ** mouse and keyboard support.  If there are buttons,
  284.    ** it returns when one is pressed & returns the ID of the
  285.    ** button.
  286.    **
  287.    ** params: db  - dialogbox structure to process
  288.    **         wnd - use already open window?
  289.    **
  290.    ** caveats: none?
  291.  */
  292.  
  293. int DoDialog(dlgbox * db, int wnd)
  294. {
  295.     WND *hWnd, *hCurr;
  296.     HotGroup Hot;
  297.     int WAttr = db->fattr;
  298.     int BAttr = db->battr;
  299.     int done = 0;               /* terminate condition */
  300.     int i;                      /* loop var */
  301.     int select = 0;
  302.     int ret = 0;
  303.     int NewFoc;
  304.     EVT event;
  305.     int Msg;                    /* Key/Mou press */
  306.  
  307.     if (!wnd)
  308.     {
  309.         hCurr = Wtop();
  310.         if ((hWnd = WndOpen(db->x1, db->y1, db->x2, db->y2, db->btype, BAttr, WAttr)) == NULL)
  311.         {
  312.             WCurr(hCurr);
  313.             return ERROR;
  314.         }
  315.     }
  316.     else
  317.         hWnd = Wtop();
  318.  
  319.     if (db->title)
  320.         WTitle(db->title, BAttr);
  321.  
  322.     for (i = 0; i < db->num; i++)
  323.     {
  324.         ShowCtrl(&db->ctrls[i], 0);
  325.     }
  326.  
  327.     BuildDialogHot(db, &Hot);
  328.     PushHotGroup(&Hot);
  329.  
  330.     Focus = 0;
  331.  
  332.     ShowCtrl(&db->ctrls[Focus], 1);
  333.     DoCursor(db, Focus);
  334.  
  335.     TTClearQue();               /* clear input queue */
  336.  
  337.     while (!done)
  338.     {
  339.         OldFocus = Focus;
  340.         /* prolly put a switch here */
  341.         if (db->ctrls[Focus].type == D_EDT)
  342.             Msg = DoEditField(&event, (editf *) db->ctrls[Focus].ctl, hWnd->wid);
  343.         else
  344.             Msg = MnuGetMsg(&event, hWnd->wid);
  345.  
  346.         switch (event.msgtype)
  347.         {
  348.         case WM_COMMAND:       /* Item pressed */
  349.             if ((NewFoc = GetFocus(db, event.id)) != -1)
  350.             {
  351.                 switch (Msg)
  352.                 {
  353.                 case LMOU_CLCK:
  354.                     Focus = NewFoc;
  355.                     if (db->ctrls[Focus].type != D_EDT)
  356.                         select = TRUE;
  357.                     break;
  358.  
  359.                 case MOU_LBTDN:
  360.                     Fo